package com.southgis.ibase.sql.utils;

import com.southgis.ibase.sql.config.DataSourceDefineTemplate;
import com.southgis.ibase.sql.config.DataSourceDefineTemplateProp;
import com.southgis.ibase.sql.enums.DataSourceType;

import lombok.extern.slf4j.Slf4j;

import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;

import javax.sql.DataSource;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.SQLException;

/**
 * 数据库工具类
 * @author young
 */
@Slf4j
public final class DatabaseUtil {

	/** 系统中配置的数据类型 */
	private static String defaultDbType=null;
	/** 配置的支持数据类型（包含定义的方言类、驱动类等信息） */
	private static DataSourceDefineTemplateProp dsTemplateProp=null;
	
	/**
	 * 初始化信息，由“DataSourceDefineTemplateProp”Bean组件调用来完成注入初始化
	 * @param dsConfig 默认数据源配置
	 * @param tempProp 数据源模板配置信息
	 * @param dataSource 默认数据源对象
	 */
	public static void init(DataSourceProperties dsConfig,DataSourceDefineTemplateProp tempProp,DataSource dataSource)
	{
		DatabaseUtil.dsTemplateProp=tempProp;
		if(dsConfig!=null) {
			defaultDbType = DataSourceType.ofByDriverOrUrl(dsConfig.getDriverClassName(),dsConfig.getUrl());
		}else if(dataSource!=null) {
			defaultDbType=getDataSourceType(dataSource);
		}
	}

	/**
	 * 获取数据源定义模板配置信息
	 * @return
	 */
	public static DataSourceDefineTemplateProp getDsTemplateProp()
	{
		if(dsTemplateProp==null) {
			dsTemplateProp=new DataSourceDefineTemplateProp();
			dsTemplateProp.init();
		}
		return dsTemplateProp;
	}
	
	/**
	 * 获取指定类型的数据源模板信息，如果找不到，返回一个通用信息的对象（这个通用对象不一定满足期望需求）
	 * @param dbType 数据源类型
	 * @return 不会返回null
	 */
	public static DataSourceDefineTemplate getDataSourceTemplate(String dbType)
	{
		return getDsTemplateProp().gainDefineTemplate(dbType);
	}
	
	/**
	 * 获取当前默认连接的数据库类型，在DataSourceType中定义的字符串。<br>
	 * 如：mysql、或 oracle。
	 * 
	 * @return
	 */
	public static String getDataSourceType() {
		return defaultDbType;
	}

	/**
	 * 从数据源中获取数据库类型，在DataSourceType中定义的字符串。<br>
	 * 如果无法判断或出错，返回空字符串（""），不会返回null。
	 * @param ds 数据源
	 * @return
	 */
	public static String getDataSourceType(DataSource ds) {
		try(Connection conn=ds.getConnection()) {
			DatabaseMetaData meta=conn.getMetaData();
			return  DataSourceType.ofByDriverOrUrl(meta.getDriverName(),meta.getURL());
		} catch (SQLException e) {
			log.warn("通过数据源获取数据库类型出错", e);
		}
		return "";
	}


}
